package com.zdj.aoplibrary.aspect;

import com.zdj.aoplibrary.annotations.SecurityCheckAnnotation;
import com.zdj.aoplibrary.util.SecurityCheckManager;
import com.zdj.utils.MyLogUtil;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


/**
 * Created by zdj on 16-7-5.
 */
@Aspect
public class SecurityAspect {

    public static final String TAG = "SecurityAspect";

    /**
     * 它在选择Jpoint的时候，把@SecurityCheckAnnotation(需要写全路径com.zdj.aoplibrary.annotations.SecurityCheckAnnotation)使用上了，这表明所有那些public的，并且携带有这个注解的API都是目标JPoint  <br/>
     * 由于我们希望在函数中获取注解的信息，所有这里的poincut函数有一个参数，参数类型是SecurityCheckAnnotation，参数名为ann
     * 这个参数我们需要在后面的advice里用上，所以pointcut还使用了@annotation(ann)这种方法来告诉 AspectJ，这个ann是一个注解
     * 作者 ：zdj <br/>
     *
     * created at 16-7-5 下午11:01
     */
    @Pointcut("execution(@com.zdj.aoplibrary.annotations.SecurityCheckAnnotation public * *..*.*(..)) && @annotation(ann)")
    public void checkPermission(SecurityCheckAnnotation ann){}

    /**
     * 接下来是advice，advice的真正功能由check函数来实现，这个check函数第二个参数就是我们想要 的注解。
     * 在实际运行过程中，AspectJ会把这个信息从JPoint中提出出来并传递给check函数。  <br/>
     * 作者 ：zdj <br/>
     * created at 16-7-5 下午11:03
     */
    @Around("checkPermission(securityCheckAnnotation)")
    public void check(ProceedingJoinPoint joinPoint, SecurityCheckAnnotation securityCheckAnnotation){
        MyLogUtil.e(TAG, "check: \n" + "点击登录按钮");
        //从注解信息中获取声明的权限。
        String neededPermission = securityCheckAnnotation.declaredPermission();
        SecurityCheckManager manager = SecurityCheckManager.getInstance();
        if(manager.checkPermission(neededPermission) == true){
//            throw new SecurityException("Need to declare permission:" + neededPermission);
            try {
                joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }else{
            return;
        }
    }
}
